package com.lai.gulimall.auth.service.impl;

import com.alibaba.fastjson.TypeReference;
import com.lai.common.constant.AuthServerConstant;
import com.lai.common.constant.ThirdPartyConstant;
import com.lai.common.exception.BizCodeEnum;
import com.lai.common.exception.RRException;
import com.lai.common.utils.R;
import com.lai.common.vo.MemberRespVo;
import com.lai.gulimall.auth.feign.MemberFeignService;
import com.lai.gulimall.auth.feign.ThirdPartFeignService;
import com.lai.gulimall.auth.service.LoginService;
import com.lai.gulimall.auth.vo.UserLoginVo;
import com.lai.gulimall.auth.vo.UserRegisterVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.concurrent.TimeUnit;

@Service
public class LoginServiceImpl implements LoginService {

    @Autowired
    ThirdPartFeignService thirdPartFeignService;

    @Autowired
    StringRedisTemplate redisTemplate;

    @Autowired
    MemberFeignService memberFeignService;



    @Override
    public boolean sendVerificationCode(String phoneNumbers,String token) throws Exception {

        //TODO 1、接口防刷

        //验证图形验证码token：
        R r1 = thirdPartFeignService.graphValidate(token);
        if(r1.getCode() == 0){
            //判断phoneNumbers在不在redis里面 如果在 并且时间过了60s，则可以继续发验证码
            String redisCode = redisTemplate.opsForValue().get(AuthServerConstant.SMS_CODE_CACHE_PREFIX + phoneNumbers);
            if(!StringUtils.isEmpty(redisCode)){
                long preTime = Long.parseLong(redisCode.split("_")[1]);
                if(System.currentTimeMillis() - preTime < 60000){ //当前时间 减去 上一次存入redis的时间   小于60s  则不能发送
                    //60s内不能继续发送
                    return false;
                }
            }

            //2、验证码的再次校验
            int verificationCode = (int) (Math.random() * 1000000);
            String code = String.valueOf(verificationCode) + "_" + System.currentTimeMillis();
            R r = thirdPartFeignService.sendVerificationCode(phoneNumbers, verificationCode);
            if (r.getCode() == 0) {
                //redis缓存验证码，防止同一个phone在60秒内再次发送验证码
                redisTemplate.opsForValue().set(AuthServerConstant.SMS_CODE_CACHE_PREFIX + phoneNumbers,code ,5, TimeUnit.MINUTES);
                return true;
            }
            return true;
        }else{
            throw new RRException(ThirdPartyConstant.Captcha.CAPTCHA_ERROR_TOKEN.getMsg(), ThirdPartyConstant.Captcha.CAPTCHA_ERROR_TOKEN.getCode());
        }

    }

    @Override
    public boolean register(UserRegisterVo vo) {
        String redisCode = redisTemplate.opsForValue().get(AuthServerConstant.SMS_CODE_CACHE_PREFIX + vo.getPhoneNumbers());
        if(!StringUtils.isEmpty(redisCode)){
            if(vo.getCode().equals(redisCode.split("_")[0])){//验证码通过
                //删除验证码； 令牌机制
                redisTemplate.delete(AuthServerConstant.SMS_CODE_CACHE_PREFIX + vo.getPhoneNumbers());
                //验证码通过，调用远程服务Member，进行注册
                R r = memberFeignService.register(vo);
                if(r.getCode() == 0){
                    return true;
                }
            }else{
                return false;
            }
        }else{
            return false;
        }
        return true;
    }

    @Override
    public MemberRespVo login(UserLoginVo userLoginVo) throws Exception {
        /* 顶象无感验证
        R r = thirdPartFeignService.graphValidate(userLoginVo.getToken());
        if(r.getCode() == 0){
            R r1 = memberFeignService.login(userLoginVo);
            if(r1.getCode() == 0){
                MemberDto memberDto = r1.getData(new TypeReference<MemberDto>() {
                });
                return memberDto;
            }else{
                throw new RRException(BizCodeEnum.ACCOUNT_PASSWORD_INVALID_EXCEPTION.getMsg(),BizCodeEnum.ACCOUNT_PASSWORD_INVALID_EXCEPTION.getCode());
            }
        }else{
            throw new RRException(ThirdPartyConstant.Captcha.CAPTCHA_ERROR_TOKEN.getMsg(), ThirdPartyConstant.Captcha.CAPTCHA_ERROR_TOKEN.getCode());
        }*/

        R r1 = memberFeignService.login(userLoginVo);
        if(r1.getCode() == 0){
            MemberRespVo memberRespVo = r1.getData(new TypeReference<MemberRespVo>() {
            });
            return memberRespVo;
        }else{
            throw new RRException(BizCodeEnum.ACCOUNT_PASSWORD_INVALID_EXCEPTION.getMsg(),BizCodeEnum.ACCOUNT_PASSWORD_INVALID_EXCEPTION.getCode());
        }
    }
}
